﻿using System;
using System.Windows.Forms;
using KryptecizerBase;
using KryptecizerBase.Encryption;
using KryptecizerBase.Decryption;
using Kryptonalysis;

namespace Kryptecizer
{
    class kr_Controller
    {
        private static kr_Controller _instance;
        private TextBasedKryptObject _kryptObject;
        private KryptoTextDecryptor _decryptor;
        private KryptoTextEncryptor _encryptor;
        private TextBasedAnalyzer _analyzer;

        public TextBasedKryptObject KryptObject { get; private set; }

        public static kr_Controller Instance 
        { 
            get
            {
                if (_instance == null)
                    _instance = new kr_Controller();
                return _instance; 
            }
        }

        public kr_Controller()
        {
            KryptObject = new TextBasedKryptObject();
        }


        /// <summary>
        /// Loads txt Files and fills the KryptObjects Text
        /// </summary>
        /// <param name="textType"></param>
        /// <param name="filePath"></param>
        internal void readTextFile(Kryptstate textType, String filePath)
        {
            String sourceText = Helpers.Filer.readFromTxtFile(filePath);
            if (sourceText != null)
            {
                switch (textType)
                {
                    case Kryptstate.DECRYPTED:
                        KryptObject.kryptoTextDecrypted.Fill(sourceText);                        
                        break;
                    case Kryptstate.ENCRYPTED:
                        KryptObject.kryptoTextEncrypted.Fill(sourceText);
                        break;
                }
            }
            else
                MessageBox.Show("An error is occured while opening file.", "opening file", MessageBoxButtons.OK, 
                    MessageBoxIcon.Error);
        }

        /// <summary>
        /// Saves thext in a txt file
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="text"></param>
        internal void saveTextToFile(String filePath, String text)
        {
            if (Helpers.Filer.writeIntoFile(filePath, text))
                MessageBox.Show("File succesful saved.", "saving file", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else
                MessageBox.Show("An error is occured while saving file.", "saving file", MessageBoxButtons.OK, 
                    MessageBoxIcon.Error);
        }

        #region CryptMethods
        /// <summary>
        /// Checks if key is valid an calls Caesarencryptmethod
        /// </summary>
        /// <param name="key"></param>
        internal void EncryptCaesar(String key, Encryptor.EncryptionProcessingEventHandler processingHandler)

        {
            int caesarKey = 0;
            try
            {
                caesarKey = Int32.Parse(key);
                _encryptor = new CaesarEncryptor(caesarKey);
                _encryptor.EncryptionEnded += encryptionEnded;
                _encryptor.EncryptionProcessing += processingHandler;
                KryptObject.Encrypt(_encryptor);
            }
            catch (InvalidCastException ce)
            {
                showInputError();
            }
            catch (FormatException fe)
            {
                showInputError();
            }
        }

        /// <summary>
        /// Checks if key is valid and calls Caesardecryptmethod
        /// </summary>
        /// <param name="key"></param>
        internal void DecryptCaesar(string key, Decryptor.DecryptionProcessingEventHandler processingHandler)
        {
            int caesarKey = 0;
            try
            {
                caesarKey = Int32.Parse(key);
                _decryptor = new CaesarDecryptor(caesarKey);
                _decryptor.DecryptionEnded += decryptionEnded;
                _decryptor.DecryptionProcessing += processingHandler;
                KryptObject.Decrypt(_decryptor);
            }
            catch (InvalidCastException ce)
            {
                showInputError();
            }
            catch (FormatException fe)
            {
                showInputError();
            }
        }

        /// <summary>
        /// Checks if key is valid an calls Vigeneredecryptmethod
        /// </summary>
        /// <param name="key"></param>
        internal void DecryptVigenere(string key, Decryptor.DecryptionProcessingEventHandler processingHandler)
        {
            _decryptor = new VigenereDecryptor(key);
            _decryptor.DecryptionEnded += decryptionEnded;
            _decryptor.DecryptionProcessing += processingHandler;
            KryptObject.Decrypt(_decryptor);
        }

        /// <summary>
        /// Checks if key is valid an calls Vigenereencryptmethod
        /// </summary>
        /// <param name="key"></param>
        internal void EncryptVigenere(string key, Encryptor.EncryptionProcessingEventHandler processingHandler)
        {
            _encryptor = new VigenereEncryptor(key);
            _encryptor.EncryptionEnded += encryptionEnded;
            _encryptor.EncryptionProcessing += processingHandler;
            KryptObject.Encrypt(_encryptor);
        }

        /// <summary>
        /// Calls the Caesaranalyzationmethods to determine Key
        /// if password found it calls the decryptmethod
        /// </summary>
        /// <returns></returns>
        internal void AnalyzeCaesar(Analyzer.AnalysisEndetEventHandler analyzisEndedHandler,
            Analyzer.AnalysisProcessingEventHandler analyzisProgressHandler,
            Decryptor.DecryptionProcessingEventHandler decryptionProgressHandler)
        {
            string detectedPassword = "";
            _analyzer = new CaesarAnalyzer();
            _analyzer.EncryptedKryptoText = KryptObject.kryptoTextEncrypted;
            _analyzer.AnalysisProcessing += analyzisProgressHandler;
            _analyzer.AnalysisEndet += analyzisEndedHandler;
            _analyzer.AnalysisEndet += analyzisEndedHandler;
            detectedPassword = _analyzer.DetectPassword();
            DecryptCaesar(detectedPassword, decryptionProgressHandler);
        }

        /// <summary>
        /// Calls the Vigenereanalyzationmethods to determine Key
        /// if password found it calls the encryptmethod
        /// </summary>
        /// <returns></returns>
        internal void AnalyzeVigenere(Analyzer.AnalysisEndetEventHandler analysisEndedHandler,
            Analyzer.AnalysisProcessingEventHandler analysisProgressHandler,
            Decryptor.DecryptionProcessingEventHandler decryptionProgressHandler)
        {
            string detectedPassword = "";
            _analyzer = new VigenereAnalyzer();
            _analyzer.EncryptedKryptoText = KryptObject.kryptoTextEncrypted;
            _analyzer.AnalysisProcessing += analysisProgressHandler;
            _analyzer.AnalysisEndet += analysisEndedHandler;
            detectedPassword = _analyzer.DetectPassword();
            if (!detectedPassword.Equals(""))
                DecryptVigenere(detectedPassword, decryptionProgressHandler);
        }

        #endregion

        private void showInputError()
        {
            MessageBox.Show("You have to chose a number to decrypt with ceasar.", 
                "key value error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }


        void decryptionEnded(bool successful)
        {
            if (successful)
                KryptObject.kryptoTextDecrypted = _decryptor.DecryptedKryptoText;
        }

        void encryptionEnded(bool successful)
        {
            if (successful)
                KryptObject.kryptoTextEncrypted = _encryptor.EncryptedKryptoText;
        }
    }
}
